﻿using System;

using System.Collections.Generic;
using System.Text;

namespace Silvermoon.Controls
{
    public class ContainerGenerator<T, D> : IDisposable
        where T : Control
    {
        private Dictionary<D, T> oldContainers = new Dictionary<D, T>();
        private Dictionary<D, T> newContainers = new Dictionary<D, T>();

        public delegate T GetContainerDelegate(D data);
        public delegate T ReleaseContainerDelegate(D data, T container);

        public ContainerGenerator(GetContainerDelegate getContainer, ReleaseContainerDelegate releaseContainer)
            : base()
        {
            this.GetContainer = getContainer;
            this.ReleaseContainer = releaseContainer;
        }

        public void Dispose()
        {
            ReleaseUnusedContainers();
        }


        public T GetContainerFromData(D data)
        {
            if (data == null) return null;
            T container;
            if (newContainers.TryGetValue(data, out container)) return container;
            if (!oldContainers.TryGetValue(data, out container))
            {
                container = this.GetContainer(data);
            }
            else
            {
                oldContainers.Remove(data);
            }
            newContainers.Add(data, container);
            return container;
        }

        public void ReleaseUnusedContainers()
        {
            foreach (var data in oldContainers.Keys)
            {
                this.ReleaseContainer(data, oldContainers[data]);
            }
            oldContainers.Clear();

            var old = oldContainers;
            oldContainers = newContainers;
            newContainers = old;
        }

        protected GetContainerDelegate GetContainer;
        protected ReleaseContainerDelegate ReleaseContainer;

    }
}
